import TDHelper from "../comm/TDHelper";
import USDate from "../comm/USDate";
import { XUtils } from "../comm/XUtils";
import { GameConfig } from "../data/GameConfig";
import LocalValues from "../data/LocalValues";
import { LoginData } from "../data/UserCtrl";
import UserModel from "../data/UserModel";
import { EventName } from "../manager/EventMgr";
import { EventMgr } from "../manager/EventMgr";
import { EventReportName } from "../net/EventReport";

export default class TDCtrl implements ITDCtrl{
    private static _instance: TDCtrl = null;
    public static get instance() {
        if (!this._instance) {
            this._instance = new TDCtrl();
        }
        return this._instance;
    }

    public init() {
        if (GameConfig.envType == 1) {
            TDHelper.init();
        }
        if (UserModel.uid) {
            this.onLogin();
        }
        this.checkInstall();
        this.countdown();
        this.lisEvents(true);
    }
    private lisEvents(bool: boolean) {
        const func = bool ? 'on' : 'off';
        EventMgr[func](EventName.onGoldChange,  this.onCoinChange, this);
    }
    onLogin(data?: LoginData) {
        console.log('###TDCtrl onLogin###');
        if (GameConfig.envType == 1) {
            TDHelper.login(UserModel.uid.toString());
        }
        if (data?.regTime) {
            this.setProp(TDProps.register_time, data.regTime);
        }
        // TDHelper.track('login', {
        //     uid: UserModel.uid,
        //     level: UserModel.curLevelId,
        // });

        // TDHelper.userSet({
        //     email: 'test@test.com',
        // });
        // TDHelper.test();
    }
    onCoinChange(coin: number): void {
        this.setProp(TDProps.current_coin, coin);
    }
    onEventReport(event: EventReportName): void {
        this.setProp(TDProps.last_active_event, event);
    }
    onAdInsert(): void {
        const count = LocalValues.addCount(TDProps.total_ads_insert);
        this.setProp(TDProps.total_ads_insert, count);
    }
    onAdRewarded(): void {
        const count = LocalValues.addCount(TDProps.total_ads_bonus);
        this.setProp(TDProps.total_ads_bonus, count);
    }
    private _gameStartTime = 0;
    onGameStart(levelId: number, retryTimes: number = 0): void {
        this._gameStartTime = Date.now();
        const playTimes = LocalValues.addCount(TDProps.levelplay_times);
        this.setProp(TDProps.levelplay_times, playTimes);
        this.setProp(TDProps.last_play_level, levelId);
        this.setProp(TDProps.last_playlevel_times, retryTimes + 1);
    }
    onGameEnd(win: boolean): void {
        if (win) {
            const completeTimes = LocalValues.addCount(TDProps.complete_times);
            this.setProp(TDProps.complete_times, completeTimes);
        } else {
            const exitTimes = LocalValues.addCount(TDProps.exit_times);
            this.setProp(TDProps.exit_times, exitTimes);
        }
        const time = (Date.now() - this._gameStartTime) / 1000;
        const playTimes = LocalValues.getCount(TDProps.levelplay_times);
        const totalTime = LocalValues.addCount(TDProps.total_level_time, time);
        const avgTime = totalTime / playTimes;
        this.setProp(TDProps.total_level_time, totalTime);
        this.setProp(TDProps.average_level_time, avgTime);
        const completeTimes = LocalValues.getCount(TDProps.complete_times);
        const winRate = completeTimes / playTimes;
        this.setProp(TDProps.level_win_rate, winRate.toFixed(4));
    }

    private _props: {[key: string]: number|string} = {};
    private _propsTimer: any;
    private setProp(name: TDProps, value: number|string) {
        console.log('###TDCtrl setProp', name, value);
        this._props[name] = value;
        if (GameConfig.envType == 1) {
            clearTimeout(this._propsTimer);
            this._propsTimer = setTimeout(() => {
                // console.log('###TDCtrl setProps', this._props);
                TDHelper.userSet(this._props);
                this._props = {};
            }, 500);
        }
    }

    private checkInstall() {
        let installTime = LocalValues.getNumber(TDProps.last_install_time);
        if (!installTime) {
            installTime = Date.now();
            LocalValues.setNumber(TDProps.last_install_time, installTime);
        }
        const str = XUtils.formatDateToSimple(installTime);
        this.setProp(TDProps.last_install_time, str);
        this.setProp(TDProps.last_install_app_version, GameConfig.version);
    }

    private countdown() {
        setInterval(() => {
            const min = LocalValues.addCount(TDProps.total_app_time);
            this.setProp(TDProps.total_app_time, min * 60);
            let regDayIdx = LocalValues.getNumber('register_day_idx');
            if (!regDayIdx) {
                let regTime = (LocalValues.getNumber(TDProps.register_time) || 0) * 1000;
                regTime = regTime || Date.now();
                regDayIdx = USDate.dayIdx(regTime);
                LocalValues.setNumber('register_day_idx', regDayIdx);
            }
            const dayIdx = USDate.dayIdx();
            const dayCount = dayIdx - regDayIdx + 1;
            const avgMin = min / dayCount;
            this.setProp(TDProps.average_app_time, avgMin);
        }, 60 * 1000);
    }
}

export enum TDProps {
    /**当前金币	数值 */
    current_coin = 'current_coin',
    /**最后上报事件	字符串 */
    last_active_event = 'last_active_event',
    /**总插屏广告观看数	数值 */
    total_ads_insert = 'total_ads_insert',
    /**总激励广告观看数	数值 */
    total_ads_bonus = 'total_ads_bonus',
    /**注册时间	时间 */
    register_time = 'register_time',
    /**总APP使用时间	数值 */
    total_app_time = 'total_app_time',
    /**日均APP使用时间	数值 */
    average_app_time = 'average_app_time',
    /**最后安装时间	时间 */
    last_install_time = 'last_install_time',
    /**最后安装版本	字符串 */
    last_install_app_version = 'last_install_app_version',
    /**总关卡内时间	数值 */
    total_level_time = 'total_level_time',
    /**完成关卡平均消耗时间	数值 */
    average_level_time = 'average_level_time',
    /**总关卡完成次数	数值 */
    complete_times = 'complete_times',
    /**总关卡进入次数	数值 */
    levelplay_times = 'levelplay_times',
    /**最后进入关卡	数值 */
    last_play_level = 'last_play_level',
    /**最后关卡进入次数	数值 */
    last_playlevel_times = 'last_playlevel_times',
    /**关卡真实胜率	字符串 */
    level_win_rate = 'level_win_rate',
    /**退出次数	数值 */
    exit_times = 'exit_times',
}

interface ITDCtrl {
    onLogin(data: LoginData): void;
    onEventReport(event: EventReportName): void;
    onAdInsert(): void;
    onAdRewarded(): void;
    onGameStart(levelId: number): void;
    onGameEnd(win: boolean): void;
}